<template>
  <!-- 添加和编辑功能 -->
  <div>
    <el-form ref="deptForm" label-width="120px" :rules="rules" :model="form">
      <el-form-item label="部门名称" prop="name">
        <el-input v-model="form.name" style="width:80%" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input v-model="form.code" style="width:80%" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门负责人" prop="manager">

        <el-select v-model="form.manager" style="width:80%" placeholder="请选择">
          <!--
            value: 选中内容之后保存在from.manager的值,会保存到v-model中
            label: 选项显示的内容
          -->
          <el-option
            v-for="employee in employees"
            :key="employee.id"
            :value="employee.username"
            :label="employee.username"
          />
        </el-select>
      </el-form-item>

      <el-form-item label="部门介绍" prop="introduce">
        <el-input v-model="form.introduce" style="width:80%" placeholder="1-300个字符" type="textarea" :rows="3" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" size="small" @click="hSubmit">确定</el-button>
        <el-button size="small" @click="hCancel">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import { getEmployeeSimple } from '@/api/employees'
import { addDepartments, getDepartDetail, updateDepartments } from '@/api/department'
export default {
  props: {
    id: { // 接收父组件传过来的部门id值
      type: String,
      required: true
    },
    isEdit: { // 接收父组件 传过来的 编辑状态
      type: Boolean,
      required: true
    },
    originList: {
      type: Array,
      required: true
    }
  },
  data() {
    const validCodes = (rule, value, callback) => { // code的自定义 校验规则
      // value 就是当前用户 输入的编码，它不能与现有的编码数据(originList)重复
      // 如果重复，就验证不通过

      // 1. 从originList([{id, pid, name, code},...])中找出全部的编码数据
      let existCodes = this.originList.map(item => item.code) // 取出已存在的部门code
      // console.log('已存在的code', existCodes)

      if (this.isEdit) { // 编辑 状态
        // 把当前正在编辑的部门编号排除在外
        console.log('现在是编辑状态，正在编辑的id是', this.id)
        // 过滤掉当前的部门, map 得到 新的部门编号列表
        existCodes = this.originList.filter(item => item.id !== this.id).map(item => item.code)
      }
      // 2. 检查value 是否存在其中
      // if (existCode.includes(value)) {
      //   callback(new Error(`编码${value}已经存在`))
      // } else {
      //   callback()
      // }

      existCodes.includes(value) ? callback(new Error(`编码${value}已经存在`)) : callback()
    }

    // 添加部门时，同级部门的名称不能使用
    // 在某个部门上点击添加时，被占用的名字列表 = 这个部门的子部门
    // const validNames = (rule, value, callback) => { // name的自定义 校验规则
    //   // console.log('validName:', value)
    //   // 被占用的名字列表 = 这个部门的子部门
    //   const existNames = this.originList.filter(item => item.pid === this.id).map(item => item.name)
    //   // console.log('被占用的名字：', existNames)
    //   if (existNames.includes(value)) {
    //     callback(new Error('名称' + value + '已经被占用了'))
    //   } else {
    //     callback()
    //   }
    // }

    const validNames = (rule, value, callback) => { // name的自定义 校验规则
      // console.log('validName:', value)
      // 被占用的名字列表 = 这个部门的子部门
      let existNames = this.originList.filter(item => item.pid === this.id).map(item => item.name)
      // console.log('被占用的名字：', existNames)

      // 编辑功能，被占用的名字 = 兄弟 - 自己
      if (this.isEdit) { // 如果是  编辑功能
        // 1. 找到当前被编辑的元素
        const dept = this.originList.find(item => item.id === this.id)
        // 2. 取出pid，根据pid找到它的同级部门
        const pid = dept.pid
        // 3. 根据pid找到它的同级部门，然后排除自己，得到同级数组对象集合，最后map:只要需要名字
        existNames = this.originList.filter(item => item.pid === pid && item.id !== this.id).map(item => item.name)
        console.log('被占用的名字：', existNames)
      }

      if (existNames.includes(value)) {
        callback(new Error('名称' + value + '已经被占用了'))
      } else {
        callback()
      }
    }
    return {
      form: {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '' // 部门介绍
      },
      employees: [],
      rules: { // 验证规则
        name: [
          { required: true, message: '部门名称不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门名称长度在4-50个字符', trigger: blur },
          { validate: validNames, trigger: blur }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门编码要求1-50个字符', trigger: ['blur', 'change'] },
          { validator: validCodes, trigger: blur }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: ['blur', 'change'] }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 300, message: '部门介绍要求1-300个字符', trigger: ['blur', 'change'] }
        ]
      }
    }
  },
  // watch: { // 被父组件中另一个方案替换了
  //   // 监听id值的变化，解决编辑时显示部门详情不准确问题
  //   id(newVal, oldVal) {
  //     // console.log('id变化了', oldVal, '------>', newVal)
  //     if (this.isEdit) { // 如果是点的 编辑功能并且 id值变化了，再去发请求获取部门详情数据
  //       this.loadDetail()
  //     }
  //   }
  // },

  created() {
    this.loadEmployees() // 下拉员工数据
    this.loadDetail() // 当前部门的详情
  },
  methods: {
    // 点表单 确定按钮
    hSubmit() {
      // this.$refs.deptForm.resetFileds() // 重置表单, 父组件@close事件统一处理了
      // 表单兜底校验
      this.$refs.deptForm.validate(valid => {
        if (valid) { // 验证通过
          // 提交数据  根据是否是 编辑状态，发送编辑功能的请求和添加功能的请求
          this.isEdit ? this.doEdit() : this.doAdd() // 调用编辑/添加的ajax请求
        }
      })
    },
    // 用户点击了取消按钮
    hCancel() {
      // 问题： 编辑部门时，故意清空某些必填项，让表单触发校验失败，然后，再次点击相同的编辑部门和点击添加子部门，发现表单内容及校验项仍在。
      // 解决：重置表单数据
      // resetFileds: element-ui 组件中的 el-form组件提供的一个api，作用是：
      // 1. 重置表单数据
      // 2. 清空校验结果(页面上红色的提示)
      // this.$refs.deptForm.resetFileds() // 父组件@close事件统一处理了

      // 通知父组件去关闭弹层
      this.$emit('hClose')
    },
    async loadEmployees() { // 获取下拉员工数据方法
      try {
        const res = await getEmployeeSimple()
        // console.log('获取下拉员工数据', res)
        this.employees = res.data
      } catch (err) {
        console.log(err)
      }
    },
    async doAdd() { // 添加功能 的 ajax请求
      // 需要组装参数 5个参数, 从props中获取pid:当前要添加的部门所在的父级的id
      // 1. 调用接口
      await addDepartments({ ...this.form, pid: this.id })
      // console.log(res)
      // 2. 通知父组件：关闭弹层，再次更新数据
      this.$emit('update-depart') // 通知父组件更新数据，关弹窗
      // 点击 对话框左上角 X，也需要重置表单，这个X是在父组件的结构
      // 需要去父组件调用 子组件重置表单方法
    },
    async loadDetail() { // 获取当前部门的详情，编辑功能数据回填
      if (this.isEdit) { // 如果是编辑状态，再去获取详情数据
        // alert('现在是编辑状态')
        const res = await getDepartDetail(this.id)
        // console.log(res)
        this.form = res.data // 当前编辑的部门信息，赋值给对象form
      }
    },
    async doEdit() { // 编辑功能 修改部门详情 ajax请求
      // 1. 调用接口.这里的this.form中已经有所有要传递的参数了
      try {
        await updateDepartments(this.form) // 回填数据from有当前部门id
        this.$message({ type: 'success', message: '修改成功' })
      } catch (err) {
        this.$message({ type: 'error', message: err.message })
      }
      // 2. 通知父组件：关闭弹层，再次更新数据
      this.$emit('update-depart') // 通知父组件更新数据，关弹窗
    },
    // 定义 重置表单 的方法
    resetForm() {
      this.$refs.deptForm.resetFields()
    }
  }
}
</script>

<style>

</style>
